package com.hw.shortlink.project.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hw.shortlink.project.common.convention.exception.ServiceException;
import com.hw.shortlink.project.dao.entity.ShortLink;
import com.hw.shortlink.project.dao.entity.ShortLinkGoto;
import com.hw.shortlink.project.dao.mapper.ShortLinkGotoMapper;
import com.hw.shortlink.project.dto.req.RecycleBinPageReqDto;
import com.hw.shortlink.project.dto.req.RecycleBinRecoverDto;
import com.hw.shortlink.project.dto.req.RecycleBinRemoveReqDto;
import com.hw.shortlink.project.dto.req.RecycleBinSaveReqDto;
import com.hw.shortlink.project.dto.resp.ShortLinkPageRespDto;
import com.hw.shortlink.project.service.RecycleBinService;
import com.hw.shortlink.project.service.ShortLinkService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.hw.shortlink.project.common.constant.RedisKeyConstants.REDIRECT_KEY;
import static com.hw.shortlink.project.common.constant.RedisKeyConstants.REDIRECT_NULL_OBJECT_KEY;


@Service
@RequiredArgsConstructor
public class RecycleBinServiceImpl implements RecycleBinService {

    private final ShortLinkService shortLinkService;

    private final StringRedisTemplate stringRedisTemplate;

    private final ShortLinkGotoMapper shortLinkGotoMapper;

    @Override
    public void saveToRecycleBin(RecycleBinSaveReqDto recycleBinSaveReqDto) {

        boolean updateResult = shortLinkService.lambdaUpdate()
                .eq(ShortLink::getGid, recycleBinSaveReqDto.getGid())
                .eq(ShortLink::getFullShortUrl, recycleBinSaveReqDto.getFullShortUrl())
                .eq(ShortLink::getDelFlag, 0)
                .eq(ShortLink::getEnableStatus, 0)
                .set(ShortLink::getEnableStatus, 1)
                .update();

        //删除缓存
        if(!updateResult){
            throw new ServiceException("移动至回收站失败");
        }
        stringRedisTemplate.delete(REDIRECT_KEY+recycleBinSaveReqDto.getFullShortUrl());

    }

    @Override
    public IPage<ShortLinkPageRespDto> pageQuery(RecycleBinPageReqDto recycleBinPageReqDto) {


        IPage<ShortLink> pageResult = shortLinkService.page(recycleBinPageReqDto, new LambdaQueryWrapper<ShortLink>()
                .in(ShortLink::getGid, recycleBinPageReqDto.getGids())
                .eq(ShortLink::getDelFlag, 0)
                .eq(ShortLink::getEnableStatus, 1)
                .orderByDesc(ShortLink::getUpdateTime));

        return pageResult.convert(shortLink -> BeanUtil.copyProperties(shortLink, ShortLinkPageRespDto.class));
    }

    @Override
    public void recover(RecycleBinRecoverDto recycleBinRecoverDto) {
        boolean updateResult = shortLinkService.lambdaUpdate()
                .eq(ShortLink::getGid, recycleBinRecoverDto.getGid())
                .eq(ShortLink::getFullShortUrl, recycleBinRecoverDto.getFullShortUrl())
                .eq(ShortLink::getDelFlag, 0)
                .eq(ShortLink::getEnableStatus, 1)
                .set(ShortLink::getEnableStatus, 0)
                .update();

        //删除缓存
        if(!updateResult){
            throw new ServiceException("复原短链接失败");
        }

        //删除缓存的空对象
        stringRedisTemplate.delete( REDIRECT_NULL_OBJECT_KEY+recycleBinRecoverDto.getFullShortUrl());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeRecycleBin(RecycleBinRemoveReqDto recycleBinRemoveReqDto) {

        shortLinkService.lambdaUpdate()
                .eq(ShortLink::getGid, recycleBinRemoveReqDto.getGid())
                .eq(ShortLink::getFullShortUrl, recycleBinRemoveReqDto.getFullShortUrl())
                .eq(ShortLink::getDelFlag, 0)
                .eq(ShortLink::getEnableStatus, 1)
                .set(ShortLink::getDelFlag, 1)
                .update();


        //删除goto表对应记录，这里是可以直接删掉的因为这个只是中间表，存储的数据数据库中还有
       shortLinkGotoMapper.delete(
               new LambdaQueryWrapper<ShortLinkGoto>()
                       .eq(ShortLinkGoto::getGid, recycleBinRemoveReqDto.getGid())
                       .eq(ShortLinkGoto::getFullShortUrl, recycleBinRemoveReqDto.getFullShortUrl()));
    }
}
